//
//  TextureManager.m
//  Void Dead
//
//  Created by Sidney Just on 03.07.09.
//  Copyright 2009 by Sidney Just
//  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; 
//  either version 3 of the License, or (at your option) any later version.
//  
//  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//  

#import "VDead.h"
#import "TextureManager.h"


@implementation VD_TextureManager
@synthesize texLib, size, hasAlpha, loadedTextures;

#pragma mark -
#pragma mark init dealloc

- (id)init {
	if(self = [super init])
	{
	}
	return self;
}

- (void)dealloc {
	glDeleteTextures(textures, &texLib[0]);
	free(texLib);
	free(loadedTextures);
	free(size);
	free(hasAlpha);
	[super dealloc];
}

#pragma mark -
#pragma mark functions

- (void)loadTexture:(NSString *)tex intoSpace:(int)ref {
	CGImageRef textureImage = [UIImage imageNamed:tex].CGImage;
	
	if (textureImage == nil) {
		NSLog(@"Failed to load texture %@", tex);
		return;
	}
	
	NSInteger texWidth = CGImageGetWidth(textureImage);	
    NSInteger texHeight = CGImageGetHeight(textureImage);
	
	size[ref] = [[VD_Vector alloc] init];
	size[ref].x = (GLfloat)texWidth;
	size[ref].y = (GLfloat)texHeight;
	
	loadedTextures[ref] = [[NSString alloc] initWithString:tex];
	
	GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
	
	CGContextRef textureContext = CGBitmapContextCreate(textureData,
														texWidth,
														texHeight,
														8, texWidth * 4,
														CGImageGetColorSpace(textureImage),
														kCGImageAlphaPremultipliedLast);
	
	CGContextDrawImage(textureContext,					   
					   CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
					   textureImage);
	
	CGContextRelease(textureContext);
	
	glGenTextures(1, &texLib[ref]);
	glBindTexture(GL_TEXTURE_2D, texLib[ref]);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
	
	free(textureData);
	
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);	
	
	VD_Image *temp = [[VD_Image alloc] init];
	[temp lockBitmap:tex];
	
	for(int x=0; x<temp.width; x++)
	{
		for(int y=0; y<temp.height; y++)
		{
			VD_Color *tempCol = [temp getBitmapColor:CGPointMake(x, y)];
			
			if(tempCol.alpha < 255)
			{
				glEnable(GL_BLEND);
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				hasAlpha[ref] = YES;
				
				[temp closeBitmap];
				[temp release];
				[tempCol release];
				
				NSLog(@"Loaded texture: %@ containing alpha", tex);
				return;
			}
			
			[tempCol release];
		}
	}
	
	hasAlpha[ref] = NO;
	
	[temp closeBitmap];
	[temp release];
	
	NSLog(@"Loaded texture: %@", tex);
}

- (int)createATexSpace {
	textures += 1;
	texLib = (GLuint *)realloc(texLib, textures * sizeof(GLuint));
	loadedTextures = (NSString **)realloc(loadedTextures, textures * sizeof(NSString *));
	size = (VD_Vector **)realloc(size, textures * sizeof(VD_Vector *));
	hasAlpha = (BOOL *)realloc(hasAlpha, textures * sizeof(BOOL));
	return textures-1;
}

- (int)loadATexture:(NSString *)str {
	int i;
	
	for(i=0; i<textures; i++)
	{
		if([str compare:loadedTextures[i]] == NSOrderedSame)
		{
			return i;
		}
	}
	i = [self createATexSpace];
	[self loadTexture:str intoSpace:i];
	
	return i;
}

- (void)deleteTexture:(NSString *)str {
	for(int i=0; i<textures; i++)
	{
		if([str compare:loadedTextures[i]] == NSOrderedSame)
		{
			[loadedTextures[i] release];
			loadedTextures[i] = [[NSString alloc] init];
			
			[size[i] release];
			size[i] = [[VD_Vector alloc] init];
			
			for(int j=i; j<textures-1; j++)
			{
				texLib[j] = texLib[j+1];
				loadedTextures[j] = loadedTextures[j+1];
				size[j] = size[j+1];
				hasAlpha[j] = hasAlpha[j+1];
			}
			
			textures -= 1;
			texLib = (GLuint *)realloc(texLib, textures * sizeof(GLuint));
			loadedTextures = (NSString **)realloc(loadedTextures, textures * sizeof(NSString *));
			size = (VD_Vector **)realloc(size, textures * sizeof(VD_Vector *));
			hasAlpha = (BOOL *)realloc(hasAlpha, textures * sizeof(BOOL));
			
			return;
		}
	}
}

@end
